<template>
  <div>
    <!-- 表单校验:rules属性传入约定的校验规则,
        并将 el-forn-item 的prop属性值定为需要验证的特殊键值,必须要有prop,才能出现红色 *-->
    <el-form :rules="spuRules" :model="spuInfo" ref="spuFormRef">
      <el-form-item label="SPU名称" prop="spuName">
        <el-input placeholder="SPU名称" v-model='spuInfo.spuName'/>
      </el-form-item>

      <el-form-item label="品牌"  prop="tmId">
        <el-select placeholder="请选择品牌" v-model="spuInfo.tmId">
          <el-option v-for="item in trademarkList" :label="item.tmName" :key="item.id" :value="item.id" />
          <el-option label="Zone two" value="beijing" />
        </el-select>
      </el-form-item>

      <el-form-item label="SPU描述" prop="description">
        <el-input type="textarea" v-model="spuInfo.description"></el-input>
      </el-form-item>

      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload v-model:file-list='spuInfo.spuImageList' :action="`${BASE_URL}/admin/product/fileUpload`" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
          <el-icon>
            <Plus />
          </el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性">
        <el-select v-model="spuInfo.spuSaleAttr" :placeholder="`还剩下${filterBaseSaleAttrList.length}个未选`">
          <el-option v-for="baseSaleAttr in filterBaseSaleAttrList" :label="baseSaleAttr.name" :value="baseSaleAttr.name" :key="baseSaleAttr.id" />
        </el-select>
        <el-button :icon="Plus" type="primary" @click="addSpuSaleAttr">添加销售属性</el-button>
      </el-form-item>
    </el-form>

    <el-form-item prop="spuSaleAttrList">
      <el-table border :data="spuInfo.spuSaleAttrList">
        <el-table-column label="序号" width="80px" type="index" align="center"></el-table-column>
        <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
        <el-table-column label="属性值名称列表">
          <template v-slot="{row}">
            <el-tag
            v-for="tag in  row.spuSaleAttrValueList"
            :key="tag"
            class="mx-1"
            closable
            :disable-transitions="false"
            @close="handleClose(tag,row)"
          >
            {{ tag.saleAttrValueName }}
          </el-tag>
          <el-input
            v-if="row.inputVisible"
            ref="InputRef"
            v-model="inputValue"
            class="ml-1 w-20"
            size="small"
            @keyup.enter="handleInputConfirm(row)"
            @blur="handleInputConfirm(row)"
          />
          <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput(row)">
            + New
          </el-button>
          </template>
        </el-table-column>

        <!-- 操作列 -->
        <el-table-column label="操作">
          <template v-slot="{$index}">
        <el-popconfirm
            confirm-button-text="确定"
            cancel-button-text="取消"
            :icon="InfoFilled"
            icon-color="#626AEF"
            title="真的确定要删除此条数据么?" 
            @confirm="deleteAttr($index)">
            
             <template #reference>
            <el-button title="删除" type="danger" size="small" :icon="Delete" />
            </template>
      </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>

    <el-form-item >
      <el-button type="primary" @click="submitSpuForm(spuFormRef)">保存</el-button>
      <el-button  @click="emits('changeScene',1)">取消</el-button>
    </el-form-item>
  </div>
</template>

<script lang="ts">
export default {
  name: 'SpuForm'
};
</script>

<script lang="ts" setup>
import { onMounted, ref, reactive, computed , nextTick} from 'vue';
import { Plus,Delete,InfoFilled} from '@element-plus/icons-vue';
import { ElMessage,ElInput } from 'element-plus';
import type { UploadProps, UploadUserFile,FormInstance, FormRules } from 'element-plus';
import { reqGetAllTrademarkList, reqGetBaseSaleAttrList,reqSaveSpuInfo,reqGetSpuImageList,reqGetSpuSaleAttrList,reqUpdateSpuInfo} from '@/api/product/spu';
import { useCategorySelectorInfoStore } from '@/stores/categorySelector'
const categoryStore = useCategorySelectorInfoStore()
const fileList = ref<UploadUserFile[]>([]);
const dialogImageUrl = ref('');
const dialogVisible = ref(false);
const trademarkList = ref([]);
const baseSaleAttrList = ref([]);
//tag标签引入的属性
const inputValue = ref('')
const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3'])
// const inputVisible = ref(false)
const InputRef = ref<InstanceType<typeof ElInput>>()
//表单校验引入的标签
const formSize = ref('default')
const ruleFormRef = ref<FormInstance>()
const spuFormRef = ref<FormInstance>()
// 接收自定义事件
const emits = defineEmits(['changeScene']) 
const props = defineProps(['currentSpuInfo'])

const handleClose = (tag: string,row:any) => {
  row.spuSaleAttrValueList.splice(row.spuSaleAttrValueList.indexOf(tag), 1)
}

const showInput = (row:any) => {
  row.inputVisible = true
  nextTick(() => {
    InputRef.value!.input!.focus()
  })
}

const handleInputConfirm = (row:any) => {
  if (inputValue.value) {
    if (row.spuSaleAttrValueList.find(item=> item.saleAttrValueName === inputValue.value)) {
      ElMessage.error('属性值不能重复,请更换一个...')
      // inputVisible.value = false
      row.inputVisible = false
      inputValue.value = ''
      return // 不再向下执行
    }
    const id = baseSaleAttrList.value.find(item=>item.name===row.saleAttrName).id
    row.spuSaleAttrValueList.push({
      saleAttrValueName:inputValue.value,
      saleAttrName: row.saleAttrName,
      baseSaleAttrId:id,
    })
  }
  row.inputVisible = false
  inputValue.value = ''
}  

//当组件渲染完毕之后,发送这两个请求
onMounted(async () => {
  try {
    //如果是更新spu,spuInfo中有id数据
    const { id } = spuInfo
    let promises = [reqGetAllTrademarkList(), reqGetBaseSaleAttrList()]
    if (id) {
    promises =  promises.concat([reqGetSpuImageList(id), reqGetSpuSaleAttrList(id)])
    }
    const [trademarkListResult, baseSaleAttrListResult, getSpuImageList, getSpuSaleAttrList] = await Promise.all(promises);
    // console.log('品牌名称和基础销售属性',trademarkListResult, baseSaleAttrListResult)
    console.log('图片和添加的销售属性',getSpuImageList,getSpuSaleAttrList);
    trademarkList.value = trademarkListResult;
    baseSaleAttrList.value = baseSaleAttrListResult;
    if (getSpuImageList && getSpuSaleAttrList) {
      //图片在服务器存储时是 imgName 和 imgUrl属性, 但是在浏览器展示是name和url属性 ,所以展示的时候要处理一下这两个属性
      spuInfo.spuImageList = getSpuImageList.map(item => ({
          ...item,
          name:item.imgName,
          url:item.imgUrl
      }))
      spuInfo.spuSaleAttrList = getSpuSaleAttrList
    }
  } catch (error) {
    ElMessage.error('获取数据失败');
  }
});

//定义一个存储SPU数据的变量 spuinfo
const spuInfo = reactive({
  spuName: '',
  tmId: '',
  description: '', // spu描述
  spuImageList: [], // 存储spu图片的数组
  spuSaleAttrList: [], // 基本销售属性
  spuSaleAttr: '', // 收集选中的属性
  category3Id: '',// 三级id
  //数据回显渲染页面需要将传过来的currentSpuInfo 覆盖 原来的空值 spuInfo
  ...props.currentSpuInfo
});

//10. 添加校验规则
const spuRules = reactive<FormRules>({
  spuName: [
    { required: true, message: '请输入SPU名字', trigger: 'blur' },
    { min: 2, max: 20, message: 'SPU名字应该在2-20之间', trigger: 'blur' },
  ],
  tmId: [
    {
      required: true,
      message: '请选择品牌',
      trigger: 'change',
    },
  ],
  description: [
    {
      required: true,
      message: '请输入SPU描述',
      trigger: 'change',
    },
  ],
  spuImageList: [
    {
      type: 'array',
      required: true,
      message: '请至少选择一张图片',
      trigger: 'change',
    },
  ],
  spuSaleAttrList: [
    {
      type: 'array',
      required: true,
      message: '请至少添加一个属性',
      trigger: 'change',
    },
  ],
 
})

// 提交前的校验
const submitSpuForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      // 再判断一下，基础销售是不是有属性值，如果有一项无值 不能提交
      const spuSaleAttrList = spuInfo.spuSaleAttrList
      if (spuSaleAttrList.length && !spuSaleAttrList.every(item => item.spuSaleAttrValueList.length)) {
        ElMessage.error('有属性值为空，请添加...')
        return // 不要添加了
      }
      // 提取一下图片的内容
      spuInfo.spuImageList = spuInfo.spuImageList.map(item => {
        return {
          //图片在服务器存储是imgName,imgUrl 属性,所以要处理一下
          imgName: item.name,
          imgUrl: item.response?.data|| item.url,
        }
      })
      spuInfo.category3Id = categoryStore.category3Id
      //提交保存spu按钮时,可能时添加或者是更新spu,根据有没有id值判断
      if (spuInfo.id) {
        // 此时是更新操作
        await reqUpdateSpuInfo(spuInfo)
      } else {
        // 才是真正的添加spuInfo
        await reqSaveSpuInfo(spuInfo)
      }

      ElMessage.success('spu添加成功...')

      emits('changeScene', 1)
    } else {
      console.log('error submit!', fields)
    }
  })
}

//定义基础url
const BASE_URL = import.meta.env.VITE_API_URL;

//图片删除
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles);
  //   // uploadFile 被删除的图片
  //   // uploadFiles 剩余的图片数据
  spuInfo.spuImageList = uploadFiles;
};
//图片预览
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

//图片上传之前的校验
const beforeAvatarUpload: UploadProps['beforeUpload'] = rawFilee => {
  const imgArr = ['image/jpeg', 'image/png', 'image/jpg'];
  // if (rawFile.type !== 'image/jpeg') {
  // console.log('rawFile',rawFile)
  if (!imgArr.includes(rawFilee.type)) {
    ElMessage.error('图片格式不正确,应该是.jpg/.png/.jpeg等');
    return false;
  } else if (rawFilee.size / 1024 / 1024 > 2) {
    ElMessage.error('图片大小不能超过2M,请重新上传...');
    //1T > 1024 G= 1024M > 1024K >1024B
    return false;
  }
  return true;
};
// 6. 添加图片成功后的操作
const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {
  //response为服务器返回的图片数据,里面有图片的链接地址,然后收集这些数据发送请求保存到数据库中
  // uploadFile 包括图片本身的信息和服务器返回的图片数据,只包含当前图片
  // uploadFiles 包括所有的上传图片
  console.log(response, uploadFile);
  spuInfo.spuImageList = uploadFiles;

  //必须要有的两个属性,服务器需要的,图片名称和图片地址
  // spuInfo.spuImageList.push({
  //   imgName: uploadFile.name,
  //   imgUrl: response.data || uploadFiles.url
  // })

  //上传成功之后清空校验规则
  spuFormRef.value!.clearValidate(['spuImageList'])
};

//7 添加销售属性值
const addSpuSaleAttr = () => {
  //如果添加属性时没有添加具体的属性值,是不可以继续添加属性的,所以添加属性时要做判断
  const spuSaleAttrList = spuInfo.spuSaleAttrList
  if (spuSaleAttrList.length && spuSaleAttrList.some(item => item.spuSaleAttrValueList.length === 0)) {
    ElMessage.error('属性值为空,请添加')
    return
  }

  //id为选中的属性的id
  const id = baseSaleAttrList.value.find(item=>item.name==spuInfo.spuSaleAttr).id 

  spuInfo.spuSaleAttrList.push({
    //属性名 , 
    saleAttrName:spuInfo.spuSaleAttr,
    //属性值列表
    spuSaleAttrValueList: [],
    //为了使每一行的销售属性值的input的输入框不互相影响,需要添加一个属性inputVisible
    inputVisible: false,
    baseSaleAttrId:id,
  });

  //清空下拉框属性名
  spuInfo.spuSaleAttr = '';

  // 清空校验规则
  spuFormRef.value!.clearValidate(['spuSaleAttrList'])
};

// 8. 使用计算属性 实现添加销售属性时移除效果
const filterBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter(item => {
     !spuInfo.spuSaleAttrList.find(obj => item.name == obj.saleAttrName);
  });
});

// 9. 删除销售属性

const deleteAttr = (index: number) => {
  spuInfo.spuSaleAttrList.splice(index,1)
}





</script>

<style lang="scss" scoped>
</style>